Namespace Auth

    Module mAuth

#Region "Login Screen Vars"

        Dim WithEvents AuthWin As GUI.MirWindow
        Dim WithEvents btnLogin As GUI.MirButton
        Dim WithEvents btnNewAccount As GUI.MirButton
        Dim WithEvents btnChangePassword As GUI.MirButton
        Dim WithEvents btnExit As GUI.MirButton
        Dim WithEvents txtUser As GUI.MirTextBox
        Public WithEvents txtPass As GUI.MirTextBox

#End Region

#Region "New Account Vars"

        Dim WithEvents NewAccountWin As GUI.MirWindow
        Dim WithEvents btnClose As GUI.MirButton
        Dim WithEvents lblNewAccount As GUI.MirText '25 20 335
        Dim WithEvents txtNewUsername As GUI.MirTextBox
        Dim WithEvents txtNewPassword As GUI.MirTextBox
        Dim WithEvents txtNewEmail As GUI.MirTextBox
        Dim WithEvents btnCreateNewAccount As GUI.MirButton

#End Region

#Region "General"

        Public Sub Init()

            '388, 204

            iBGIndex = 21 + Int(Rnd() * 14)

            AuthWin = New GUI.MirWindow("winAuth", (Constants.gGameResX - Constants.gLoginResX) / 2, (Constants.gGameResY - Constants.gLoginResY) / 2, Constants.gLoginResX, Constants.gLoginResY)
            btnLogin = New GUI.MirButton(AuthWin, "btnLogin", 460, 438, 0.2, EvoLib.Protocol.ImgLibs.Interface1c, 11, 12, , , False)
            btnNewAccount = New GUI.MirButton(AuthWin, "btnNewAccount", 139, 379, 0.19, EvoLib.Protocol.ImgLibs.Interface1c, 13, 14, , , False)
            btnChangePassword = New GUI.MirButton(AuthWin, "btnChangePassword", 279, 379, 0.19, EvoLib.Protocol.ImgLibs.Interface1c, 15, 16, , , False)
            btnExit = New GUI.MirButton(AuthWin, "btnExit", 439, 379, 0.19, EvoLib.Protocol.ImgLibs.Interface1c, 17, 18, , , False)
            txtUser = New GUI.MirTextBox(AuthWin, "txtUser", 127, 436, 15, EvoLib.Protocol.MAX_USERNAME_LEN, DirectX.ProFont9, , , , 7, EvoLib.Protocol.VALID_USERNAME_CHARS)
            txtPass = New GUI.MirTextBox(AuthWin, "txtPass", 325, 436, 15, EvoLib.Protocol.MAX_PASSWORD_LEN, DirectX.ProFont9, True, , , 7, EvoLib.Protocol.VALID_PASSWORD_CHARS)

            Windows.AddWindow(AuthWin, Windows.WindowType.AlwaysBottom)

            txtUser.Text = Globals.iniConfig.GetString("AUTOLOGIN", "UID", "")
            txtPass.Text = Globals.iniConfig.GetString("AUTOLOGIN", "PWD", "")

            NewAccountWin = New GUI.MirWindow("winNewAccount", (Constants.gGameResX - Constants.gLoginResX) / 2, (Constants.gGameResY - Constants.gLoginResY) / 2, Constants.gLoginResX, Constants.gLoginResY, False)
            Dim xpos As Integer = (Constants.gLoginResX \ 2) - 194
            Dim ypos As Integer = (Constants.gLoginResY \ 2) - 102
            btnClose = New GUI.MirButton(NewAccountWin, "btnClose", xpos + 350, ypos + 25 + Libs.GameInter.Image(381).Header.Height, 0.1, EvoLib.Protocol.ImgLibs.GameInter, 1221, 1222, 1223, "Close", False)

            Dim arCols As New ArrayList
            arCols.Add(Color.White)
            lblNewAccount = New GUI.MirText(NewAccountWin, "lblNewAccount", xpos + 25, ypos + 20, DirectX.ProFont9, "\b\0New Account\b\n\nPlease enter your desired username and password below, along with a valid email address.\n\nUsername:\n\nPassword:\n\n\n   Email:", Color.Transparent, Color.Transparent, arCols, 0, 0, 335, 335)

            txtNewUsername = New GUI.MirTextBox(NewAccountWin, "txtNewUsername", xpos + 80, ypos + 80, 25, EvoLib.Protocol.MAX_USERNAME_LEN, DirectX.ProFont9, , "Username", , , EvoLib.Protocol.VALID_USERNAME_CHARS)
            txtNewPassword = New GUI.MirTextBox(NewAccountWin, "txtNewPassword", xpos + 80, ypos + 104, 25, EvoLib.Protocol.MAX_PASSWORD_LEN, DirectX.ProFont9, True, "Password", , , EvoLib.Protocol.VALID_PASSWORD_CHARS)
            txtNewEmail = New GUI.MirTextBox(NewAccountWin, "txtNewEmail", xpos + 80, ypos + 140, 35, EvoLib.Protocol.MAX_EMAIL_LEN, DirectX.ProFont9, , "Email Address", , , EvoLib.Protocol.VALID_EMAIL_CHARS)

            SetTextBoxColors(txtNewUsername)
            SetTextBoxColors(txtNewPassword)
            SetTextBoxColors(txtNewEmail)

            btnCreateNewAccount = New GUI.MirButton(NewAccountWin, "btnCreateNewAccount", xpos + 225, ypos + 170, 0.1, EvoLib.Protocol.ImgLibs.EvoInterface, 15, 16, 17, , False)

            Globals.gGameState = Globals.GameState.Auth
            'MessageBoxes.SetStateNotice("Connecting to server...")

            Sound.PlayBGM(Sound.GetBGMFile(Sound.BGM.Opening), 100)

        End Sub

        Public Sub Shutdown()

            Windows.RemoveWindow(AuthWin)

            Sound.StopAllSounds()

            Libs.Interface1c.UnloadImages()

        End Sub

        Public Sub PacketArrival(ByRef info As EvoLib.Protocol.Packet, ByRef struct() As Byte)

            Select Case CType(info.PacketType, EvoLib.Protocol.LoginPacketType)

                Case EvoLib.Protocol.LoginPacketType.TryLogin
                    Select Case info.PacketOpCode
                        Case PacketOpCode.NegAcknowledge
                            'login has failed display error message

                            Dim msg As String = EvoLib.Protocol.Functions.ArrayToStruct(struct, GetType(EvoLib.Protocol.GenericMessage)).message
                            MessageBoxes.AddMessageBox("LOGINFAIL", msg, MessageBoxes.MsgBoxButtons.OK, _
                                                        AddressOf MsgBoxResultCallback)
                            txtPass.Text = ""
                            MessageBoxes.RemoveStateNotice()
                            Globals.sUsername = Protocol.DefaultUsername
                            'Globals.Crypto = Cryptography.DefaultCrypto

                    End Select

                    '    Select Case info.PacketOpCode

                    '        Case EvoLib.Protocol.PacketOpCode.Acknowledge
                    '            System.Threading.Thread.Sleep(250)

                    '            MessageBoxes.RemoveStateNotice()

                    '            Auth.Shutdown()
                    '            SelectChar.Init()

                    '    End Select

                Case Protocol.LoginPacketType.TryMagicPacket
                    Select Case info.PacketOpCode

                        Case PacketOpCode.Enquiry
                            'server is asking for the magic packet, md5 hash has not yet been transmitted and will instead be used for the encryption key


                            'random string for magic handshake
                            Dim bRand As Protocol.GenericMessage
                            bRand.MESSAGE = Chr(Functions.RandNum(0, 255)) & Chr(Functions.RandNum(0, 255)) & Chr(Functions.RandNum(0, 255)) & Chr(Functions.RandNum(0, 255))
                            'packet header
                            Dim p As Packet
                            p.PacketType = LoginPacketType.TryMagicPacket
                            p.PacketOpCode = PacketOpCode.Answer
                            p.Username = Globals.sUsername

                            'tmp crypto from md5 hash of pass to encrypt magic packet with
                            Dim tmpCrypto As Cryptography.Crypto = New EvoLib.Cryptography.Crypto(EvoLib.Protocol.Functions.MD5Hash(txtPass.Text))

                            'send magic packet
                            ClientSock.SendData(MakePacket(p, bRand, tmpCrypto))
                        Case EvoLib.Protocol.PacketOpCode.Acknowledge
                            'server has managed to decrypt the magic packet and is acknowledging the login has succeded

                            'set global crypto object using md5 hash
                            Globals.Crypto = New EvoLib.Cryptography.Crypto(EvoLib.Protocol.Functions.MD5Hash(txtPass.Text))

                            'sleep 1/4 sec
                            System.Threading.Thread.Sleep(250)

                            'remove "Authenticating..." state notice
                            MessageBoxes.RemoveStateNotice()

                            'goto sel char screen
                            Auth.Shutdown()
                            SelectChar.Init()
                    End Select

                Case EvoLib.Protocol.LoginPacketType.TryNewLogin
                    Select Case info.PacketOpCode

                        Case EvoLib.Protocol.PacketOpCode.Acknowledge
                            Dim msg As String = EvoLib.Protocol.Functions.ArrayToStruct(struct, GetType(EvoLib.Protocol.GenericMessage)).message
                            MessageBoxes.AddMessageBox("NEWLOGINOK", msg, MessageBoxes.MsgBoxButtons.OK, _
                                                        AddressOf MsgBoxResultCallback)
                            MessageBoxes.RemoveStateNotice()

                        Case EvoLib.Protocol.PacketOpCode.NegAcknowledge
                            Dim msg As String = EvoLib.Protocol.Functions.ArrayToStruct(struct, GetType(EvoLib.Protocol.GenericMessage)).message
                            MessageBoxes.AddMessageBox("NEWLOGINFAIL", msg, MessageBoxes.MsgBoxButtons.OK, _
                                                        AddressOf MsgBoxResultCallback)
                            MessageBoxes.RemoveStateNotice()

                    End Select

                Case EvoLib.Protocol.GamePacketType.DisconnectClient
                    Select Case info.PacketOpCode
                        Case EvoLib.Protocol.PacketOpCode.Notify
                            MessageBoxes.AddMessageBox("DISCONNECT", "Disconnected from server due to lack of socket activity!", MessageBoxes.MsgBoxButtons.OK, AddressOf MsgBoxResultCallback)
                    End Select

            End Select

        End Sub

        Public Sub MsgBoxResultCallback(ByRef result As MessageBoxes.MsgBoxResult)

            Select Case result.mName

                Case Is = "LOGINFAIL"

                Case Is = "EXIT"
                    If result.mResult = MessageBoxes.MsgBoxResults.Yes Then
                        Globals.bEnding = True
                    End If

                Case Is = "NEWLOGINOK"
                    Call btnClose_Click

            End Select

        End Sub

#End Region

#Region "Login Screen"

        Private Sub AuthWin_DrawWindow(ByRef mode As Globals.DrawingMode, ByRef x As Integer, ByRef y As Integer, ByRef z As Single) Handles AuthWin.DrawWindow

            With Libs.Interface1c

                If mode = Globals.DrawingMode.Normal Then

                    'draw background
                    .Image(iBGIndex).Draw(x, y, z + 0.01)

                    'draw logo
                    'Libs.EvoInterface.Image(1).Draw(x + 16, y + 16, z)

                    'user\pass boxes
                    .Image(3).Draw(x + 100, y + 436, z)

                ElseIf mode = Globals.DrawingMode.SemiTransparent Then

                    .Image(2).Draw(x, y + Constants.gLoginResY - 60 - .Image(2).Header.Height, z) '+ 0.01)

                ElseIf mode = Globals.DrawingMode.Line Then

                    'gray box for new account\change pass\exit
                    Engine.DrawBox(x, x + Constants.gLoginResX - 1, y + Constants.gLoginResY - 60 - .Image(2).Header.Height, y + Constants.gLoginResY - 60, z, 1, Color.FromArgb(99, 101, 99))

                End If

            End With

        End Sub

        Private Sub btnExit_Click() Handles btnExit.Click
            Sound.PlaySoundEffect(Sound.GetSoundEffectFile(Sound.SoundEffects.Click), 100)
            MessageBoxes.AddMessageBox("EXIT", "Do you really want to exit?", MessageBoxes.MsgBoxButtons.YesNo, AddressOf MsgBoxResultCallback)
        End Sub

        Private Sub btnNewAccount_Click() Handles btnNewAccount.Click
            Sound.PlaySoundEffect(Sound.GetSoundEffectFile(Sound.SoundEffects.ClickGo), 100)

            Windows.AddWindow(NewAccountWin, Windows.WindowType.AlwaysOnTop)
            Timers.AddTimer("NewAccountWinFade", 10, 192, True)
        End Sub

        Private Sub btnChangePassword_Click() Handles btnChangePassword.Click
            Sound.PlaySoundEffect(Sound.GetSoundEffectFile(Sound.SoundEffects.Click), 100)
            MessageBoxes.AddMessageBox("SORRY", "Sorry, not coded yet!", MessageBoxes.MsgBoxButtons.OK, AddressOf MsgBoxResultCallback)
        End Sub

        Private Sub btnLogin_Click() Handles btnLogin.Click
            ConfirmInputs()
        End Sub

        Private Sub txtPass_Enter() Handles txtPass.Enter
            ConfirmInputs()
        End Sub

        Private Sub txtPass_TabSwitch() Handles txtPass.TabSwitch
            Sound.PlaySoundEffect(Sound.GetSoundEffectFile(Sound.SoundEffects.Click), 100)
            Windows.FocusInterface(txtUser)
        End Sub

        Private Sub txtUser_Enter() Handles txtUser.Enter
            ConfirmInputs()
        End Sub

        Private Sub txtUser_TabSwitch() Handles txtUser.TabSwitch
            Sound.PlaySoundEffect(Sound.GetSoundEffectFile(Sound.SoundEffects.Click), 100)
            Windows.FocusInterface(txtPass)
        End Sub

        Private Sub ConfirmInputs()
            If txtUser.Text.Length > 0 And txtPass.Text.Length > 0 Then
                Sound.PlaySoundEffect(Sound.GetSoundEffectFile(Sound.SoundEffects.ClickGo), 100)
                TryLogin()
            Else
                Sound.PlaySoundEffect(Sound.GetSoundEffectFile(Sound.SoundEffects.Click), 100)
                If txtUser.Text.Length = 0 Then
                    Windows.FocusInterface(txtUser)
                ElseIf txtPass.Text.Length = 0 Then
                    Windows.FocusInterface(txtPass)
                End If
            End If
        End Sub

        Public Sub TryLogin(Optional auto As Boolean = False)

            'If bCanLogin Then

            '    Dim reply As EvoLib.Protocol.Packet
            '    reply.Username = Globals.sUsername
            '    reply.PacketType = EvoLib.Protocol.LoginPacketType.TryLogin
            '    reply.PacketOpCode = EvoLib.Protocol.PacketOpCode.Enquiry

            '    Dim uid As EvoLib.Protocol.UserLogin
            '    If auto Then
            '        uid = Auth.AutoLoginID
            '    Else
            '        uid.STR_USERNAME = txtUser.Text
            '        uid.STR_PASSMD5 = EvoLib.Protocol.Functions.MD5Hash(txtPass.Text)
            '    End If

            '    ClientSock.SendData(EvoLib.Protocol.MakePacket(reply, uid, Globals.Crypto))

            '    MessageBoxes.SetStateNotice("Authenticating...")

            'End If

            Dim p As Protocol.Packet

            p.PacketType = Protocol.LoginPacketType.TryLogin
            p.PacketOpCode = Protocol.mProtocol.PacketOpCode.Enquiry
            p.Username = Protocol.DefaultUsername

            Globals.sUsername = txtUser.Text

            Dim struct As Protocol.UserLogin

            struct.STR_USERNAME = txtUser.Text
            struct.STR_CLIENTVER = Protocol.sClientVersion

            ClientSock.SendData(Protocol.MakePacket(p, struct, EvoLib.Cryptography.DefaultCrypto))

            MessageBoxes.SetStateNotice("Authenticating...")

        End Sub

#End Region

#Region "New Account"

        Private Sub SetTextBoxColors(ByRef txtbox As GUI.MirTextBox)

            txtbox.SetNormColors(Color.FromArgb(255, 8, 8, 8), Color.Gray, Color.White)
            txtbox.SetFocusedColors(Color.FromArgb(255, 8, 8, 8), Color.DarkGray, Color.White)

        End Sub

        Private Sub NewAccountWin_DrawWindow(ByRef mode As Globals.DrawingMode, ByRef x As Integer, ByRef y As Integer, ByRef z As Single) Handles NewAccountWin.DrawWindow


            If mode = Globals.DrawingMode.Line Then

                Engine.DrawSolidBox(New Rectangle(0, 0, Constants.gGameResX, Constants.gGameResY), z + 0.02, Color.FromArgb(30 + Timers.GetTimer("NewAccountWinFade"), 80, 80, 105))

            ElseIf mode = Globals.DrawingMode.Normal Then

                Dim xpos As Integer = (Constants.gGameResX \ 2) - 194
                Dim ypos As Integer = (Constants.gGameResY \ 2) - 102

                Libs.GameInter.Image(381).Draw(xpos, ypos, z + 0.01)
                Libs.GameInter.Image(383).Draw(xpos + 1, ypos + Libs.GameInter.Image(381).Header.Height, z + 0.01)

            End If


        End Sub

        Private Sub btnClose_Click() Handles btnClose.Click
            Sound.PlaySoundEffect(Sound.GetSoundEffectFile(Sound.SoundEffects.ClickGo), 100)
            Windows.RemoveWindow(NewAccountWin)
            Timers.RemoveTimer("NewAccountWinFade")
        End Sub

        Private Sub txtNewUsername_TabSwitch() Handles txtNewUsername.TabSwitch
            Sound.PlaySoundEffect(Sound.GetSoundEffectFile(Sound.SoundEffects.Click), 100)
            Windows.FocusInterface(txtNewPassword)
        End Sub

        Private Sub txtNewPassword_TabSwitch() Handles txtNewPassword.TabSwitch
            Sound.PlaySoundEffect(Sound.GetSoundEffectFile(Sound.SoundEffects.Click), 100)
            Windows.FocusInterface(txtNewEmail)
        End Sub

        Private Sub txtNewEmail_TabSwitch() Handles txtNewEmail.TabSwitch
            Sound.PlaySoundEffect(Sound.GetSoundEffectFile(Sound.SoundEffects.Click), 100)
            Windows.FocusInterface(txtNewUsername)
        End Sub

        Private Sub btnCreateNewAccount_Click() Handles btnCreateNewAccount.Click
            Sound.PlaySoundEffect(Sound.GetSoundEffectFile(Sound.SoundEffects.Click), 100)

            'If bCanLogin Then

            If txtNewPassword.Text.Length < EvoLib.Protocol.MIN_PASSWORD_LEN Then
                MessageBoxes.AddMessageBox("NEWLOGINFAIL", "Password must be at least " & EvoLib.Protocol.MIN_PASSWORD_LEN & " characters!", MessageBoxes.MsgBoxButtons.OK, _
                                            AddressOf MsgBoxResultCallback)
                Exit Sub
            End If

            Dim reply As EvoLib.Protocol.Packet
            reply.Username = Globals.sUsername
            reply.PacketType = EvoLib.Protocol.LoginPacketType.TryNewLogin
            reply.PacketOpCode = EvoLib.Protocol.PacketOpCode.Enquiry

            Dim uid As EvoLib.Protocol.NewUserLogin
            uid.STR_USERNAME = txtNewUsername.Text
            uid.STR_PASSMD5 = EvoLib.Protocol.Functions.MD5Hash(txtNewPassword.Text)
            uid.STR_EMAIL = txtNewEmail.Text

            ClientSock.SendData(EvoLib.Protocol.MakePacket(reply, uid, Cryptography.DefaultCrypto))

            MessageBoxes.SetStateNotice("Creating Account Please Wait...")

            'End If

        End Sub

#End Region

    End Module

End Namespace